﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Extensions.DependencyInjection;

using zijian666.Core;
using zijian666.Core.Abstractions;
using zijian666.DI.Abstractions;

namespace zijian666.DI.Autowired.Net8;

internal class KeyedServiceAutowiredFeature : IAutowiredFeature, IAutoRefreshMultiSlot<IAutowiredFeature>
{
    public int Order { get; } = 1;
    private IAutowiredFeature _baseFeature = null!;
    public void MultiSet(IEnumerable<IAutowiredFeature> features)
    {
        _baseFeature = features.First(x => x.Order == 0);
    }

    private static Func<IServiceProvider, object?, object>? BuildFactory(ServiceDescriptor serviceDescriptor)
    {
        var serviceType = serviceDescriptor.ServiceType;
        var implementationType = serviceDescriptor.KeyedImplementationType;


        if (serviceDescriptor.KeyedImplementationInstance is var implementationInstance and not null)
        {
            return (p, k) => p.Autowired(() => implementationInstance);
        }

        if (serviceDescriptor.KeyedImplementationFactory is var implementationFactory and not null)
        {
            return (p, k) => p.Autowired(() => implementationFactory(p, k));
        }

        return (p, k) => p.Autowired(() => ActivatorUtilities.CreateInstance(p, implementationType ?? serviceType));
    }
    /// <summary>
    /// 代理服务描述
    /// </summary>
    public ServiceDescriptor Proxy(ServiceDescriptor serviceDescriptor)
    {
        if (CantProxy(serviceDescriptor))
        {
            return serviceDescriptor;
        }
        if (!serviceDescriptor.IsKeyedService)
        {
            return _baseFeature.Proxy(serviceDescriptor);
        }
        var factory = BuildFactory(serviceDescriptor);
        if (factory is null)
        {
            return serviceDescriptor;
        }
        return new AutowirableServiceDescriptor(serviceDescriptor, factory);
    }


    private static bool CantProxy(ServiceDescriptor serviceDescriptor)
    {
        if (serviceDescriptor is AutowirableServiceDescriptor)
        {
            return true;
        }
        if (serviceDescriptor.ServiceType is null)
        {
            return true;
        }
        // 泛型服务无法注入 [Autowired]
        if (serviceDescriptor.ImplementationType is { IsGenericType: true, IsGenericTypeDefinition: true })
        {
            return true;
        }
        return false;
    }
    public object? GetService(IAutowiredContext context, AutowiredDescriptor descriptor, Type serviceType)
    {
        if (!descriptor.IsKeyedService)
        {
            return _baseFeature.GetService(context, descriptor, serviceType);
        }
        var provider = context.Services;
        var key = descriptor.Attribute.Key;
        if (provider is IKeyedServiceProvider keyedServiceProvider)
        {
            return keyedServiceProvider.GetKeyedService(serviceType, key);
        }
        return provider.GetKeyedServices(serviceType, key).FirstOrDefault();
    }

    /// <summary>
    /// 用于代理系统的服务描述，以完成自动装配的动作
    /// </summary>
    private sealed class AutowirableServiceDescriptor(ServiceDescriptor serviceDescriptor, Func<IServiceProvider, object?, object> factory)
        : ServiceDescriptor(serviceDescriptor.ServiceType, serviceDescriptor.ServiceKey, factory, serviceDescriptor.Lifetime)
    {

    }


}
